package com.one.system.service.sysuser.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.one.common.core.constants.HttpConstants;
import com.one.common.core.domain.LoginUser;
import com.one.common.core.domain.R;
import com.one.common.core.domain.vo.LoginUserVO;
import com.one.common.core.enums.ResultCode;
import com.one.common.core.enums.UserIdentity;
import com.one.common.security.exception.ServiceException;
import com.one.common.security.service.TokenService;
import com.one.system.domain.sysuser.SysUser;
import com.one.system.domain.sysuser.dto.SysUserSaveDTO;
import com.one.system.mapper.sysuser.SysUserMapper;
import com.one.system.service.sysuser.ISysUserService;
import com.one.system.utils.BCryptUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RefreshScope
public class SysUserServiceImpl implements ISysUserService {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private TokenService tokenService;

    @Value("${jwt.secret}")
    private String secret;


    @Override
    public R<String> login(String userAccount, String password){
        //实现，通过账号从数据库查询数据
        //select userId,password,nickName from sys_user where user_account = #{user_account}
        SysUser sysUser = sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUserAccount,userAccount));
        // 测试一下全局异常处理
//        int i = 10 / 0;
//        System.out.println(i);
        //登录数据效验
        if(sysUser == null){
            //用户不存在
//            r.setCode(ResultCode.FAILED_USER_NOT_EXISTS.getCode());
//            r.setMsg(ResultCode.FAILED_USER_NOT_EXISTS.getMsg());
//            return r;
            return R.fail(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        if(BCryptUtils.matchesPassword(password,sysUser.getPassword())){
            //登录成功
//            r.setCode(ResultCode.SUCCESS.getCode());
//            r.setMsg(ResultCode.SUCCESS.getMsg());
//            return r;
            //1. 用户登录账号密码后，需生成一个token，把token返回给客户端存储
            //2. 用户后续所有的接口访问都需要发送token，进行身份认证
            //3. 通过第三方组件对token进行过期时间设置，每次登录都刷新过期的时间,适当延长有效时间

            // TokenService

            return R.ok(tokenService.createToken(sysUser.getUserId(),sysUser.getNickName(),
                    secret, UserIdentity.ADMIN.getValue(),null));
        }
        //登录失败，账号或密码错误
//        r.setCode(ResultCode.FAILED_LOGIN.getCode());
//        r.setMsg(ResultCode.FAILED_LOGIN.getMsg());
//        return r;
        return R.fail(ResultCode.FAILED_LOGIN);

        //代码不仅要实现其功能，还要考虑其维护性，安全性等
    }

    @Override
    public int add(SysUserSaveDTO sysUserSaveDTO) {
        //优化的关键原因就是重复
        List<SysUser> sysUserList = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().select()
                .eq(SysUser::getUserAccount, sysUserSaveDTO.getUserAccount()));

        if(CollectionUtil.isNotEmpty(sysUserList)){
            throw new ServiceException(ResultCode.AILED_USER_EXISTS);
        }
        //将dto转换为实体
        SysUser sysUser = new SysUser();
        sysUser.setUserAccount(sysUserSaveDTO.getUserAccount());
        sysUser.setPassword(BCryptUtils.encryptPassword(sysUserSaveDTO.getPassword()));
//        String token = getToken(request);
//        Claims claims = JwtUtils.parseToken(token,secret);
//        String userId = JwtUtils.getUserId(claims);
//        //从数据库中拿出当前用户的信息
//        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
//        SysUser curUser = sysUserMapper.selectOne(queryWrapper.select(SysUser::getUserAccount)
//                .eq(SysUser::getUserId,userId));
//
//        sysUser.setCreateBy(curUser.getUserAccount());//获取到当前操作人，拿到当前用户token，根据userid查到用户信息(拿到用户id即可)
//        sysUser.setCreateTime(LocalDateTime.now());
//        sysUser.setUpdateBy(curUser.getUserAccount());//更新人就是当前操作人
//        sysUser.setUpdateTime(LocalDateTime.now());
        //插入数据库
        return sysUserMapper.insert(sysUser);
//        //插入成功
//        if(insert > 0){
//            return R.fail();
//        }
//        return R.ok();
    }

    @Override
    public R<LoginUserVO> info(String token) {
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        //拿到存储在redis当中的昵称信息，返回给前端展示
        LoginUser loginUser = tokenService.getLoginUser(token,secret);
        if(loginUser == null) {
            return R.fail();
        }
        LoginUserVO loginUserVO = new LoginUserVO();
        loginUserVO.setNickName(loginUser.getNickName());
        return R.ok(loginUserVO);
    }

    @Override
    public boolean logout(String token) {
        if (StrUtil.isNotEmpty(token) && token.startsWith(HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX, StrUtil.EMPTY);
        }
        //根据token中的信息删除掉redis当中的token
        return tokenService.deleteToken(token,secret);
    }

}
